/*
 * BuffTimeResource.cpp
 *
 *  Created on: 2014. 1. 14.
 *      Author: mega
 */

#include "../User.h"
#include "../NUtil/Utils.h"
#include "BuffTimeResource.h"
#include <Database/Static.h>

namespace ProjectZ { namespace NResource {

BuffTimeResource::BuffTimeResource()
{
	pBuffTimeAD		= new BuffTimeData;
	pBuffTimeIOS	= new BuffTimeData;
}

BuffTimeResource::~BuffTimeResource()
{
	delete pBuffTimeAD;
	delete pBuffTimeIOS;
}

BuffTimeResource::BuffTimeData::BuffTimeData()
{

}

BuffTimeResource::BuffTimeData::~BuffTimeData()
{
	Clear();
}

void
BuffTimeResource::BuffTimeData::Clear()
{
	std::for_each(clsBuffTimeMap.begin(), clsBuffTimeMap.end(), [&](BUFFTIMEMAP::value_type & value) {
		std::for_each(value.second.begin(), value.second.end(), [&](Flyweight * pFly) {
			delete pFly;
		} );
	} );
	clsBuffTimeMap.clear();
}

BuffTimeResource::BuffTimeData *
BuffTimeResource::GetBuffTimeDataPtr(User * pUser)
{
	NUtil::MarketType marketType = NUtil::GetMarketType(pUser->GetCompany(), pUser->GetSaleCode());

	switch (marketType)
	{
	case NUtil::MarketType::AD_KAKAO:
		return pBuffTimeAD;

	case NUtil::MarketType::IOS_KAKAO:
		return pBuffTimeIOS;

	default:
		return NULL;
	}

	return NULL;
}

bool
BuffTimeResource::LoadResource()
{
	if (false == pBuffTimeAD->LoadResource(MARKET_GOOGLE, SC_KAKAO_GOOGLE))
		return false;

	if (false == pBuffTimeIOS->LoadResource(MARKET_IOS, SC_KAKAO_IOS))
		return false;

	return true;
}

bool
BuffTimeResource::BuffTimeData::LoadResource(int company, int salecode)
{
	::Database::Command::Auto clsAuto(::Database::GETCOMMANDPOOL());
	clsAuto->SetQueryType(::Database::Command::SELECT);
	clsAuto->MakeQuery("SELECT * FROM resource_buff_time WHERE COMPANY=%d AND SALE_CODE=%d ORDER BY BUFF_TYPE, RATE DESC", company, salecode);

	if (false == ::Database::GETSESSION()->SyncExecute(1, clsAuto))
		return false;

	if( clsAuto->GetErrorIdx() != 0 )
		return false;

	if (0 == clsAuto->ResultRowCount())
		return false;

	Clear();

	while (clsAuto->Next())
	{
		::Toolkit::Str<3> NATIONAL_CODE;
		int tmpCompany;
		int tmpSaleCode;
		int buffType;
		Flyweight * pFly = new Flyweight;

		clsAuto->GetRecord() >> NATIONAL_CODE >> tmpCompany >> tmpSaleCode >> buffType >> pFly->_MINUTE >> pFly->_RATE;

		if (0 != Config::Instance().GetResourceDatabase()._strNational.compare(NATIONAL_CODE.c_str()))
		{
			DEBUGLOG("%s:%d NATIONAL_CODE ERROR!!! Config National Code [%s] , Resource National Code [%s]",
					__FILE__, __LINE__,
					Config::Instance().GetResourceDatabase()._strNational.c_str(),
					NATIONAL_CODE.c_str());
			return false;
		}

		FLYWEIGHTVECTOR & flyweightVector = clsBuffTimeMap[buffType];
		flyweightVector.push_back(pFly);
	}

//	PrintBuffTime(company, salecode);

	return true;
}

BuffTimeResource::BuffTimeData::FLYWEIGHTVECTOR &
BuffTimeResource::BuffTimeData::GetFlyVector(int buffType)
{
	return clsBuffTimeMap[buffType];
}

int
BuffTimeResource::GetWinPointBuffContinueMinute(User * pUser)
{
	/*
	 * 승점 버프의 유지시간을 구한다.
	 * @return : 유지시간(분)
	 */

	int retMinute	= -1;
	int accRate		= 0;
	int randRate	= rand() % 100;
	int buffType	= static_cast<int>(BuffType::EM_WINPOINT_BUFF);

	BuffTimeData * pBuffTimeData = GetBuffTimeDataPtr(pUser);
	if (NULL == pBuffTimeData)
	{
		DEBUGLOG("%s : pBuffTimeData is NULL", __FUNCTION__);
		return -1;
	}

	BuffTimeData::FLYWEIGHTVECTOR & flyweightVector = pBuffTimeData->GetFlyVector(buffType);

//	DEBUGLOG("%s : VectorSize=%d, randRate=%d", __FUNCTION__, flyweightVector.size(), randRate);

	auto iter = flyweightVector.begin();

	for (; iter != flyweightVector.end(); ++iter)
	{
		BuffTimeData::Flyweight * pFly = ( * iter);

		accRate += pFly->_RATE;

//		DEBUGLOG("%s : rate=%d, accRate=%d", __FUNCTION__, pFly->_RATE, accRate);

		if (randRate < accRate)
		{
			retMinute = pFly->_MINUTE;
			break;
		}
	}

	return retMinute;
}

void
BuffTimeResource::BuffTimeData::PrintBuffTime(int company, int salecode)
{
	{
		int buffType	= static_cast<int>(BuffType::EM_WINPOINT_BUFF);

		FLYWEIGHTVECTOR & flyweightVector = clsBuffTimeMap[buffType];

		auto iter = flyweightVector.begin();

		for (; iter != flyweightVector.end(); ++iter)
		{
			Flyweight * pFly = ( * iter);
			DEBUGLOG("company=%d, salecd=%d, buffType=%d, minute=%d, rate=%d", company, salecode, buffType, pFly->_MINUTE, pFly->_RATE);
		}
	}

	DEBUGLOG("-------------------------------------------------------");

	{
		int buffType	= static_cast<int>(BuffType::EM_GUILD_BUFF);

		FLYWEIGHTVECTOR & flyweightVector = clsBuffTimeMap[buffType];

		auto iter = flyweightVector.begin();

		for (; iter != flyweightVector.end(); ++iter)
		{
			Flyweight * pFly = ( * iter);
			DEBUGLOG("company=%d, salecd=%d, buffType=%d, minute=%d, rate=%d", company, salecode, buffType, pFly->_MINUTE, pFly->_RATE);
		}
	}

	DEBUGLOG("-------------------------------------------------------");
}

} /*NResource*/ } /*ProjectZ*/
